
import { MBSenseMode, MBSocketEvent } from './mb_constants';

import MBCore from './mb_core'
import MBUtils from './mb_utils'
import MBDataSender from './mb_data_sender'

class MBKeepAliveDaemon {
    private intervalId: any = 0;
    private KEEP_ALIVE_INTERVAL: any = 5000;
    private NETWORK_CONNECTION_TIME_OUT: any = this.KEEP_ALIVE_INTERVAL + 3000;
    private lastGetKeepAliveResponseFromServerTimstamp: any = 0;
    private networkConnectionLostCallback: any = null;
    private keepAliveTaskExcuting: any = false;
    private keepAliveWillStop: any = false;



    excute() {
        if (!this.keepAliveTaskExcuting) {
            this.keepAliveWillStop = false;
            this.onKeepAlive(this.doKeepAlive());
        }
    };


    doKeepAlive() {
        this.keepAliveTaskExcuting = true;
        return MBDataSender.sendKeepAlive();
    }


    onKeepAlive(code: any) {
        // 给应用层发出ping事件通知
        MBCore.emit(MBSocketEvent.SOCKET_EVENT_PING, null);

        // 首先执行Keep Alive心跳包时，把此时的时间作为第1次收到服务响应的时间（初始化）
        let isInitialedForKeepAlive = (this.lastGetKeepAliveResponseFromServerTimstamp === 0);
        //## 解决极端情况下网络断开时，无法进入下面的"断开"通知流程
        if (isInitialedForKeepAlive)
            this.lastGetKeepAliveResponseFromServerTimstamp = MBUtils.getCurrentUTCTimestamp();

        // 首先启动心跳时就不判断了，否则就是逻辑有问题
        if (!isInitialedForKeepAlive) {
            let now = MBUtils.getCurrentUTCTimestamp();

            // 当当前时间与最近一次服务端的心跳响应包时间间隔>= 10秒就判定当前与服务端的网络连接已断开
            if (now - this.lastGetKeepAliveResponseFromServerTimstamp >= this.NETWORK_CONNECTION_TIME_OUT) {
                if (MBCore.debugEnabled()) {
                    console.log(">>>> t1=" + now + ", t2=" + this.lastGetKeepAliveResponseFromServerTimstamp
                        + " -> 差：" + (now - this.lastGetKeepAliveResponseFromServerTimstamp));
                    console.log("心跳机制已判定网络断开，将进入断网通知和重连处理逻辑 ...");
                }

                this.notifyConnectionLost();
                this.keepAliveWillStop = true;
            }
        }

        this.keepAliveTaskExcuting = false;
        if (this.keepAliveWillStop) {
            // 停止心跳循环
            this.stop();
        }
    }

    notifyConnectionLost() {
        // 先停止心跳线程
        this.stop();
        // 再通知“网络连接已断开”
        if (this.networkConnectionLostCallback != null)
            this.networkConnectionLostCallback(null, null);
    }

    start(immediately: any) {
        this.stop();

        // 立即执行1次
        if (immediately) {
            this.excute();
        }

        let that = this;
        // 定时执行
        this.intervalId = setInterval(function () {
            that.excute();
        }, this.KEEP_ALIVE_INTERVAL);
    }


    stop() {
        if (this.intervalId && this.intervalId !== 0) {
            clearInterval(this.intervalId);
        }
        this.lastGetKeepAliveResponseFromServerTimstamp = 0;
    }


    updateGetKeepAliveResponseFromServerTimstamp() {
        this.lastGetKeepAliveResponseFromServerTimstamp = MBUtils.getCurrentUTCTimestamp();
    }


    setNetworkConnectionLostCallback(networkConnectionLostCallback: any) {
        this.networkConnectionLostCallback = networkConnectionLostCallback;
    }


    setSenseMode(senseMode: any) {
        let keepAliveInterval = 0;
        let networkConnectionTimeout = 0;
        switch (senseMode) {
            case MBSenseMode.MODE_3S: {
                // 心跳间隔3秒
                keepAliveInterval = 3000;// 3s
                // 5秒后未收到服务端心跳反馈即认为连接已断开（相当于连续1个心跳间隔+2秒链路延迟容忍时间后仍未收到服务端反馈）
                networkConnectionTimeout = keepAliveInterval * 1 + 2000;// 5s
                break;
            }
            case MBSenseMode.MODE_5S: {
                // 心跳间隔5秒
                keepAliveInterval = 5000;// 5s
                // 8秒后未收到服务端心跳反馈即认为连接已断开（相当于连续1个心跳间隔+3秒链路延迟容忍时间后仍未收到服务端反馈）
                networkConnectionTimeout = keepAliveInterval * 1 + 3000;// 8s
                break;
            }
            case MBSenseMode.MODE_10S: {
                // 心跳间隔10秒
                keepAliveInterval = 10000;// 10s
                // 15秒后未收到服务端心跳反馈即认为连接已断开（相当于连续1个心跳间隔+5秒链路延迟容忍时间后)后仍未收到服务端反馈）
                networkConnectionTimeout = keepAliveInterval * 1 + 5000;// 15s
                break;
            }
            case MBSenseMode.MODE_15S: {
                // 心跳间隔15秒
                keepAliveInterval = 15000;// 15s
                // 20秒后未收到服务端心跳反馈即认为连接已断开（相当于连续1个心跳间隔+5秒链路延迟容忍时间后)后仍未收到服务端反馈）
                networkConnectionTimeout = keepAliveInterval * 1 + 5000;// 20s
                break;
            }
            case MBSenseMode.MODE_30S: {
                // 心跳间隔30秒
                keepAliveInterval = 30000;// 30s
                // 35秒后未收到服务端心跳反馈即认为连接已断开（相当于连续1个心跳间隔+5秒链路延迟容忍时间后)后仍未收到服务端反馈）
                networkConnectionTimeout = keepAliveInterval * 1 + 5000;// 35s
                break;
            }
            case MBSenseMode.MODE_60S: {
                // 心跳间隔60秒
                keepAliveInterval = 60000;// 60s
                // 65秒后未收到服务端心跳反馈即认为连接已断开（相当于连续1个心跳间隔+5秒链路延迟容忍时间后)后仍未收到服务端反馈）
                networkConnectionTimeout = keepAliveInterval * 1 + 5000;// 65s
                break;
            }
            case MBSenseMode.MODE_120S: {
                // 心跳间隔120秒
                keepAliveInterval = 120000;// 120s
                // 125秒后未收到服务端心跳反馈即认为连接已断开（相当于连续1个心跳间隔+5秒链路延迟容忍时间后)后仍未收到服务端反馈）
                networkConnectionTimeout = keepAliveInterval * 1 + 5000;// 125s
                break;
            }
        }

        if (keepAliveInterval > 0) {
            // 设置Kepp alive心跳间隔
            this.KEEP_ALIVE_INTERVAL = keepAliveInterval;
        }

        if (networkConnectionTimeout > 0) {
            // 设置与服务端掉线的超时时长
            this.NETWORK_CONNECTION_TIME_OUT = networkConnectionTimeout;
        }
    }


}

export default new MBKeepAliveDaemon();